package edu.bu.cs673.superkids123.children.controller;

import java.util.Date;
import java.util.List;

import edu.bu.cs673.superkids123.AbstractController;
import edu.bu.cs673.superkids123.AbstractFrame;
import edu.bu.cs673.superkids123.children.DataObjectAccess.ReportManager;
import edu.bu.cs673.superkids123.children.model.CompletedGame;
import edu.bu.cs673.superkids123.children.model.Game;
import edu.bu.cs673.superkids123.children.model.resources.AudioPlayer;
import edu.bu.cs673.superkids123.children.model.resources.ChildrenResourceProvider;
import edu.bu.cs673.superkids123.common.model.Achievement;
import edu.bu.cs673.superkids123.common.model.Child;

// TODO: Auto-generated Javadoc
/**
 * AbstractGameController
 * 
 * Abstract base class for all Game controller classes.
 * Basic audio support is available and shared by each game controller
 * that requires it.
 * 
 * @author bhepburn
 * @author David Bardwell
 * @author Adam Phung
 *
 */
public abstract class AbstractGameController extends AbstractController{
	
	/** The provider. */
	private ChildrenResourceProvider provider = ChildrenResourceProvider.getInstance();

	private Game game;
	private CompletedGame completedGame;
	private boolean active;
	// TODO: implement setter/getter for this
	private List<Achievement> earnedAchievements;
	
	
	/**
	 * Instantiates a new abstract game controller.
	 *
	 * @param mainFrame the main frame
	 */
	public AbstractGameController(AbstractFrame mainFrame) {
		super(mainFrame);
	}
	
	/**
	 * Gets the audio sampled data.
	 *
	 * @param numberToPlay the number to play
	 * @return the audio sampled data
	 */
	private byte[] getAudioSampledData(int numberToPlay) {
		byte[] audioData = null;
		
		audioData = provider.getAudioContentByNumber(numberToPlay);
		return audioData;
	}
	
	/**
	 * playAudioForNumber.
	 *
	 * @param number the number
	 */
	public void playAudioForNumber(int number) {
		AudioPlayer audioPlayer = new AudioPlayer();
		byte[] audioData = getAudioSampledData(number); 
		audioPlayer.playAudio(audioData);
		try {
			Thread.sleep(100);
		}
		catch (InterruptedException ie) {
			System.out.println("Thread interrupted");
		}
	}
	
	/**
	 * Start game report recording
	 *
	 * @param Game being recorded
	 */
	public void start(Game g) {
		active = true;
		game = g;
		completedGame = new CompletedGame();
		completedGame.setGame(game);
		completedGame.setStartDate(new Date());
		Child child = (Child) authController.getCurrentUser();
		completedGame.setChild(child);
		completedGame.setCompleted(false);
	}
	
	/**
	 * Stops the game report.
	 *
	 * @param complete true for complete, false for incomplete
	 * @param score integer from 0-100;
	 */
	public void stop(boolean complete, int score) {
		active = false;
		completedGame.setEndDate(new Date());
		completedGame.setCompleted(complete);
		
		// Precondition: score must be between 0-100
		score = score < 0 ? 0 : score;
		score = score > 100 ? 100 : score;
		
		completedGame.setScore(score);
		
		// Save to DB
		ReportManager.addCompletedGame(completedGame);
		
		// Award Achievements
		setEarnedAchievements(getMainFrame().getController(AchievementController.class).awardAchievements());
	}
	
	/**
	 * Returns true if an active game is occurring.
	 * @return boolean
	 */
	public boolean isActive() {
		return active;
	}

	public List<Achievement> getEarnedAchievements() {
		return earnedAchievements;
	}

	public void setEarnedAchievements(List<Achievement> earnedAchievements) {
		this.earnedAchievements = earnedAchievements;
	}
}
